﻿#include "CVlcRtspOper.h"
#include <QPainter>
#include <QCoreApplication>
#include "CGlobal.h"
#include "CModelMng.h"

CVlcRtspOper::CVlcRtspOper(CDevDataCam *pDevDataCam, const QString &url, QWidget *pWidget)
	:m_pMediaPlayer(nullptr),
	m_pMedia(nullptr),
	m_cCurrentFrame(1920, 1080, QImage::Format_RGB32), // 使用更高效的格式
	m_frameBuffer(1920, 1080, QImage::Format_RGB32),   // 初始化重用缓冲区
	m_bInit(false),
	m_lastFrameTime(0),
	m_targetFps(30), // 默认15帧
	m_frameCount(0),
	m_actualFps(0),
	m_destroying(false)  // 在初始化列表中初始化
{
	m_pDevDataCam = pDevDataCam;
	m_pImageLabel = static_cast<QLabel*>(pWidget);
	if (m_pImageLabel) {
		m_pImageLabel->setScaledContents(true);
	}
	m_sUrl = url;

	// 配置线程池
	int optimalThreadCount = QThread::idealThreadCount();
	m_threadPool.setMaxThreadCount(qMax(2, optimalThreadCount - 1)); // 留一个核心给UI线程
	m_threadPool.setExpiryTimeout(30000); // 30秒空闲后线程退出

	m_frameTimer.start(); // 启动帧率计时器
}
CVlcRtspOper::~CVlcRtspOper()
{
	m_destroying.store(true);  // 先设置销毁标志

	// 先断开所有连接
	if (m_pFrameTimer) 
	{
		m_pFrameTimer->stop();
		disconnect(m_pFrameTimer, nullptr, this, nullptr);
	}

	disconnect(this, nullptr, this, nullptr);

	stopCapture();
	// 给VLC更多时间完成回调
	for (int i = 0; i < 5; ++i)
	{
		QThread::msleep(50);
		QCoreApplication::processEvents();
	}

	// 清空线程池
	m_threadPool.clear();
	m_threadPool.waitForDone(2000);

	// 最后释放VLC资源
	if (m_pMediaPlayer)
	{
		libvlc_media_player_release(m_pMediaPlayer);
		m_pMediaPlayer = nullptr;
	}

	if (m_pMedia) 
	{
		libvlc_media_release(m_pMedia);
		m_pMedia = nullptr;
	}
}

bool CVlcRtspOper::startCapture()
{
	init();
	if (m_pMediaPlayer)
	{
		libvlc_media_player_play(m_pMediaPlayer);
	}
	if (m_pFrameTimer) 
	{
		m_pFrameTimer->start(100);
		return true;
	}
	return false;
}

bool CVlcRtspOper::stopCapture()
{
	if (m_pMediaPlayer) 
	{
		libvlc_media_player_stop(m_pMediaPlayer);
	}

	if (m_pFrameTimer && m_pFrameTimer->isActive()) 
	{
		m_pFrameTimer->stop();
	}

	QThread::msleep(200);
	return true;
}

void CVlcRtspOper::init()
{
	if (m_bInit) {
		return;
	}

	// 创建媒体
	m_pMedia = libvlc_media_new_location(CModelMng::instance().m_pVlcInstance, m_sUrl.toStdString().c_str());
	if (!m_pMedia) {
		qFatal("Failed to open media.");
		return;
	}

	// 设置VLC网络参数
	if (m_pMedia)
	{
		// 降低网络缓存
		libvlc_media_add_option(m_pMedia, ":network-caching=100");
		libvlc_media_add_option(m_pMedia, ":rtsp-tcp"); // 使用TCP
		libvlc_media_add_option(m_pMedia, ":no-audio"); // 禁用音频
		libvlc_media_add_option(m_pMedia, ":drop-late-frames"); // 丢弃延迟帧
	}

	// 创建媒体播放器
	m_pMediaPlayer = libvlc_media_player_new_from_media(m_pMedia);
	if (!m_pMediaPlayer) {
		qFatal("Failed to create media player.");
		libvlc_media_release(m_pMedia);
		m_pMedia = nullptr;
		return;
	}

	// 设置回调
	libvlc_video_set_callbacks(m_pMediaPlayer, lockCallback, unlockCallback, nullptr, this);
	libvlc_video_set_format(m_pMediaPlayer, "RV32",
		m_cCurrentFrame.width(),
		m_cCurrentFrame.height(),
		m_cCurrentFrame.bytesPerLine());

	m_pFrameTimer = new QTimer(this);
	connect(m_pFrameTimer, &QTimer::timeout, this, &CVlcRtspOper::slot_CaptureFrame);

	m_bInit = true;
}

void * CVlcRtspOper::lockCallback(void * opaque, void ** planes)
{
	auto *self = static_cast<CVlcRtspOper *>(opaque);

	// 检查对象是否正在销毁
	if (self->m_destroying.load()) 
	{
		return nullptr;
	}

	self->m_frameLock.lockForWrite();

	// 再次检查，避免竞态条件
	if (self->m_destroying.load()) 
	{
		self->m_frameLock.unlock();
		return nullptr;
	}

	*planes = self->m_cCurrentFrame.bits();
	return nullptr;
}

void CVlcRtspOper::unlockCallback(void * opaque, void * picture, void * const * planes)
{
	Q_UNUSED(picture);
	Q_UNUSED(planes);

	auto *self = static_cast<CVlcRtspOper *>(opaque);

	// 只有在对象有效时才解锁
	if (!self->m_destroying.load()) 
	{
		self->m_frameLock.unlock();
	}
}

void CVlcRtspOper::safeUpdateUI(QPixmap pixmap)
{
	// 现在可以安全地操作UI，因为已经在UI线程中
	if (!m_pImageLabel || m_destroying.load()) return;

	if (!pixmap.isNull())
	{
		const QPixmap* currentPixmap = m_pImageLabel->pixmap();
		if (!currentPixmap || currentPixmap->cacheKey() != pixmap.cacheKey())
		{
			m_pImageLabel->setPixmap(pixmap);
			m_pImageLabel->update();
		}
	}
}

void CVlcRtspOper::slot_CaptureFrame()
{
	if (m_destroying.load() || !m_pImageLabel || !m_bInit) return;

	// 精确的帧率控制
	qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
	if (currentTime - m_lastFrameTime < (1000 / m_targetFps)) {
		return;
	}
	m_lastFrameTime = currentTime;

	// 帧率统计（可选，用于调试）
	m_frameCount++;
	if (m_frameTimer.elapsed() >= 1000) {
		m_actualFps = m_frameCount;
		m_frameCount = 0;
		m_frameTimer.restart();
		// qDebug() << "实际帧率:" << m_actualFps;
	}

	// 快速拷贝帧数据，减少锁持有时间
	QImage frameCopy;
	{
		QReadLocker locker(&m_frameLock);
		if (m_cCurrentFrame.isNull() || m_destroying.load()) return;
		frameCopy = m_cCurrentFrame.copy();
	}

	if (m_destroying.load()) return;

	// 创建处理任务
	FrameProcessor *processor = new FrameProcessor(
		frameCopy,
		QSize(m_pImageLabel->width() - 2, m_pImageLabel->height() - 2)
	);

	connect(processor, &FrameProcessor::frameProcessed,
		this, &CVlcRtspOper::onFrameProcessed,
		Qt::QueuedConnection);

	m_threadPool.start(processor);
}

void CVlcRtspOper::onFrameProcessed(QPixmap pixmap)
{
	if (!m_pImageLabel || m_destroying.load()) return;

	if (QThread::currentThread() == m_pImageLabel->thread()) {
		// 已经在UI线程，直接操作
		safeUpdateUI(pixmap);
	}
	else {
		// 在其他线程，使用 invokeMethod 切换到UI线程
		QMetaObject::invokeMethod(this, "safeUpdateUI",
			Qt::QueuedConnection,
			Q_ARG(QPixmap, pixmap));
	}
}

FrameProcessor::FrameProcessor(const QImage &frame, const QSize &targetSize)
	: m_frame(frame)
	, m_targetSize(targetSize)
{
	setAutoDelete(true); // 任务完成后自动删除
}

void FrameProcessor::run()
{
	if (m_frame.isNull()) return;

	QImage scaledFrame = m_frame.scaled(m_targetSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
	emit frameProcessed(QPixmap::fromImage(scaledFrame));
}